﻿using Codemonk.Common.Caching;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Xml;

namespace Codemonk.Soya
{
    internal static class DelegateExtensions
    {
        public static void SafeInvoke(this Action action)
        {
            try
            {
                action();
            }
            catch { }
        }
        public static T SafeInvoke<T>(this Func<T> func, T defaultValue = default(T))
        {
            try
            {
                return func();
            }
            catch { return defaultValue; }
        }
    }
    internal static class ConverterExtensions
    {
        private static Dictionary<string, Type> simpleValueConverters = new Dictionary<string, Type> {
            {"sbyte",typeof(sbyte) } ,
            {"byte",  typeof(byte) } ,
            {"short", typeof(short) } ,
            {"ushort",typeof(ushort) } ,
            {"int", typeof(int)  } ,
            {"uint",typeof(uint)  } ,
            {"long",  typeof(long) } ,
            {"ulong",typeof(ulong)  } ,
            {"char", typeof(char)  } ,
            {"float",typeof(float)  } ,
            {"double",typeof(double) } ,
            {"bool ",typeof(bool) } ,
            {"string",typeof(string) },
            {"list",typeof(List<string>) }};
 
        public static T As<T>(this string input, Func<string, T> parser, T defaultValue = default(T))
        {
            Func<T> p = () => parser(input);
            return p.SafeInvoke<T>(defaultValue);
        }
        public static string AsString(this string input, string defaultValue = "")
        {
            Func<string> p = () => input + "";
            return p.SafeInvoke<string>(defaultValue);
        }
        public static int AsInt32(this string input, int defaultValue = 0)
        {
            Func<int> p = () => int.Parse(input);
            return p.SafeInvoke<int>(defaultValue);
        }
        public static bool AsBoolean(this string input, bool defaultValue = false)
        {
            Func<bool> p = () => bool.Parse(input);
            return p.SafeInvoke<bool>(defaultValue);
        }
        public static float AsFloat(this string input, float defaultValue = 0f)
        {
            Func<float> p = () => float.Parse(input);
            return p.SafeInvoke<float>(defaultValue);
        }
        public static double AsDouble(this string input, double defaultValue = 0d)
        {
            Func<double> p = () => double.Parse(input);
            return p.SafeInvoke<double>(defaultValue);
        }
        public static decimal AsDecimal(this string input, decimal defaultValue = 0m)
        {
            Func<decimal> p = () => decimal.Parse(input);
            return p.SafeInvoke<decimal>(defaultValue);
        }
        public static Regex AsRegex(this string input, Regex defaultValue = null)
        {
            Func<Regex> p = () => new Regex(input, RegexOptions.Compiled);
            return p.SafeInvoke<Regex>(defaultValue);
        }
        public static Type AsType(this string input, Type defaultValue = null)
        {
            Func<Type> p = () =>
            {
                Type type = null;
                if (simpleValueConverters.TryGetValue(input, out type)) return type;
                return Type.GetType(input);
            };
            return p.SafeInvoke<Type>(defaultValue);
        }
    }
    internal static class XmlExtensions
    {
        public static T As<T>(this XmlNode input, string xpath, Func<string, T, T> parser, T defaultValue = default(T), bool isValue = true)
        {
            Func<T> p = () => parser(isValue ? input.SelectSingleNode(xpath).Value : input.SelectSingleNode(xpath).InnerText, defaultValue);
            return p.SafeInvoke<T>(defaultValue);
        }

    }
}
